using Microsoft.UI;
using Microsoft.UI.Text;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using System;
using System.Collections.ObjectModel;
using System.Linq;
using TextNovelReader.Model;
using TextNovelReader.Services;
using Windows.UI;
using Windows.UI.ViewManagement;
using WinRT;


namespace TextNovelReader.Views;

public sealed partial class MainPage : Page
{
    private readonly DispatcherTimer _timer;
    private readonly UISettings _uiSettings; 

    public MainPageViewModel ViewModel { get; }
    public MainPage()
    {
        InitializeComponent();
        
        ViewModel = new();
        GlobalServices.Settings.FilePathChanged += OpenNewTextFileAsync;
        GlobalServices.Settings.FontSizeChanged += SetFontSize;
        GlobalServices.Settings.WhiteLinesChanged += ViewModel.OnWhiteLinesChanged;
        GlobalServices.Settings.ThemeIndexChanged += SetReaderTheme;
        GlobalServices.Events.ReaderScrollRequested += ScrollReader;
        GlobalServices.Events.ChapterIndexDeltaModified += Variables_ChapterIndexDeltaModified;
        GlobalServices.Events.HideListViewRequested += Events_HideListViewRequested;
        GlobalServices.Settings.FontNameChanged += SetReaderFont;

        _uiSettings = new();
        _uiSettings.ColorValuesChanged += SystemColorChanged;
        
        ApplyUserSettings();

        _timer = new()
        {
            Interval = TimeSpan.FromMilliseconds(50)
        };
        _timer.Tick += UpdateUiTimer_Tick;
        _timer.Start(); 
    }

    private void ApplyUserSettings()
    {
        SetFontSize(GlobalServices.Settings.FontSize);
        SetReaderTheme(GlobalServices.Settings.ThemeIndex);
        SetReaderFont(GlobalServices.Settings.FontName);
    }

    private void SetReaderFont(string fontName)
    {
        if (App.Current.Resources[fontName] is FontFamily fontFamily)
        {
            ReaderTextBlock.FontFamily = fontFamily; 
        }
    }

    private void Events_HideListViewRequested(bool hide)
    {
        ContentsGrid.Visibility = hide ? Visibility.Collapsed : Visibility.Visible;
    }

    private void Variables_ChapterIndexDeltaModified(int delta)
    {
        var newIndex = GlobalServices.Settings.ChapterIndex + delta; 
        if (newIndex >= 0 && newIndex < ViewModel.BookChapters.Count)
        {
            TitlesListView.SelectedIndex = newIndex; 
        }
    }

    private void SystemColorChanged(UISettings sender, object args)
    {
        DispatcherQueue.TryEnqueue(() =>
        {
            SetReaderTheme(GlobalServices.Settings.ThemeIndex);
        });
    }

    private async void OpenNewTextFileAsync(string filePath)
    {
        if (string.IsNullOrEmpty(filePath))
            return; 

        await ViewModel.GetChaptersFromFileAsync(filePath);
        if (ViewModel.BookChapters.Count > 0)
        {
            TitlesListView.SelectedIndex = 0;
            GlobalServices.Settings.ChapterIndex = 0; 
        }
    }

    private async void UpdateUiTimer_Tick(object? sender, object e)
    {
        await ViewModel.GetChaptersFromFileAsync(GlobalServices.Settings.FilePath);
        if(ViewModel.BookChapters.Any())
        {
            TitlesListView.SelectedIndex = GlobalServices.Settings.ChapterIndex;
        }
        _timer.Stop(); 
    }

    private void SetReaderTheme(int themeIndex)
    {
        string theme = "Theme_"; 
        if(themeIndex == -1)
            theme += SystemService.IsSystemDarkMode() ? "Dark" : "White";
        else
            theme += $"{themeIndex}";

        ReaderScrollView.Style = (Style)App.Current.Resources[theme];
    }

    private void ScrollReader(double direction)
    {
        double speed = direction * GlobalServices.Settings.ScrollSpeed; 
        ReaderScrollView.ScrollBy(0, speed); 
    }

    private void SetFontSize(double fontSize)
    {
        ReaderTextBlock.FontSize = fontSize;
    }

    private void AutoSuggestBox_TextChanged(AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
    {
        if (ViewModel.BookChapters.Count == 0)
            return;

        if (string.IsNullOrEmpty(sender.Text))
            return; 

        if(args.Reason == AutoSuggestionBoxTextChangeReason.UserInput)
        {
            string input = sender.Text;
            ObservableCollection<Chapter> items = []; 
            
            foreach(Chapter chapter in ViewModel.BookChapters)
            {
                if (chapter.Title.Contains(input))
                {
                    items.Add(chapter);
                    if (items.Count == 8)
                        break; 
                }
            }
            sender.ItemsSource = items; 
        }
    }

    private void AutoSuggestBox_SuggestionChosen(AutoSuggestBox sender, AutoSuggestBoxSuggestionChosenEventArgs args)
    {
        Chapter chapter = args.SelectedItem.As<Chapter>(); 
        TitlesListView.SelectedItem = chapter; 
        sender.Text = string.Empty;
        ReaderScrollView.ScrollTo(0, 0); 
    }

    private void TitlesListView_SelectionChanged(object sender, SelectionChangedEventArgs args)
    {
        if (args.AddedItems.Count == 0)
            return;

        Chapter chapter = args.AddedItems[0].As<Chapter>();
        ViewModel.UpdateSelectedChapter(chapter);
        TitlesListView.ScrollIntoView(chapter);
        ReaderScrollView.ScrollTo(0, 0);
    }
}
